package doc;

public class checker02 {
    
    private int score;
    private String result;
    
    public static final String TOO_SHORT = "Too Short";
    public static final String VERY_WEAK = "Very Weak";
    public static final String WEAK = "Weak";
    public static final String MEDIUM = "Medium";
    public static final String STRONG = "Strong";
    public static final String VERY_STRONG = "Very Strong";
    
    private final int MIN_PASSWORD_LENGTH = 8;
    
//    private char[] sAlphas = "abcdefghijlmnopqrstuvwxyz".toCharArray();
//    private char[] sNumerics = "01234567890".toCharArray();
//    private char[] sSymbols = ")!@#$%^&*()".toCharArray();
    private String sAlphas = "abcdefghijlmnopqrstuvwxyz";
    private String sNumerics = "01234567890";
    private String sSymbols = ")!@#$%^&*()";

    public String getResult() {
        return result;
    }

    public int getScore() {
        return score;
    }

    public void checkPassword(String pwd) {
        score = 0; 
        int nLength = 0, nAlphaUC = 0, nAlphaLC = 0, nNumber = 0, nSymbol = 0, nMidChar = 0,
                nRequirements = 0, nUnqChar = 0, nRepChar = 0,
                nConsecAlphaUC = 0, nConsecAlphaLC = 0, nConsecNumber = 0, nConsecSymbol = 0,
                nConsecCharType = 0, nSeqAlpha = 0, nSeqNumber = 0, nSeqSymbol = 0, nSeqChar = 0,
                nReqChar = 0;
        //int nMultConsecCharType = 0;
        int nAlphasOnly = 0, nNumbersOnly = 0;
        double nRepInc = 0.0;
        
        //int nMultRepChar = 1, nMultConsecSymbol = 1;
        int nMultMidChar = 2, nMultConsecAlphaUC = 2, nMultConsecAlphaLC = 2, nMultConsecNumber = 2;
        //int nMultRequirements = 2;
        int nMultSeqAlpha = 3, nMultSeqNumber = 3, nMultSeqSymbol = 3;
        //int nReqCharType = 3, nMultAlphaUC = 3, nMultAlphaLC = 3;
        int nMultLength = 4, nMultNumber = 4, nMultSymbol = 6;
        
        int nTmpAlphaUC = -1, nTmpAlphaLC = -1, nTmpNumber = -1, nTmpSymbol = -1;
        String sAlphaUC = "0", sAlphaLC = "0", sNumber = "0", sSymbol = "0", sMidChar = "0", sRequirements = "0",
                sAlphasOnly = "0", sNumbersOnly = "0", sRepChar = "0", sConsecAlphaUC = "0", sConsecAlphaLC = "0",
                sConsecNumber = "0", sSeqAlpha = "0", sSeqNumber = "0", sSeqSymbol = "0";
        
        sAlphas = "abcdefghijlmnopqrstuvwxyz";
        sNumerics = "01234567890";
        sSymbols = ")!@#$%^&*()";
        result = "Too Short";

        if (isPasswordValid(pwd)) {
            score = pwd.length() * nMultLength;
            nLength = pwd.length();
            char[] pwd2 = pwd.replaceAll("\\s+", "").toCharArray();
            int arrPwdLen = pwd2.length;

            for (int i = 0; i < arrPwdLen; i++) {
                if (Character.isLetter(pwd2[i]) && Character.isUpperCase(pwd2[i])) {
                    if (nTmpAlphaUC != -1) {
                        if ((nTmpAlphaUC + 1) == i) {
                            nConsecAlphaUC++;
                            nConsecCharType++;
                        }
                    }
                    nTmpAlphaUC = i;
                    nAlphaUC++;
                } else if (Character.isLetter(pwd2[i]) && Character.isLowerCase(pwd2[i])) {
                    if (nTmpAlphaLC != -1) {
                        if ((nTmpAlphaLC + 1) == i) {
                            nConsecAlphaLC++;
                            nConsecCharType++;
                        }
                    }
                    nTmpAlphaLC = i;
                    nAlphaLC++;
                } else if (Character.isDigit(pwd2[i])) {
                    if (i > 0 && i < (arrPwdLen - 1)) {
                        nMidChar++;
                    }
                    if (nTmpNumber != -1) {
                        if ((nTmpNumber + 1) == i) {
                            nConsecNumber++;
                            nConsecCharType++;
                        }
                    }
                    nTmpNumber = i;
                    nNumber++;
                } else if (!Character.isDigit(pwd2[i]) && !Character.isLetter(pwd2[i]) && pwd2[i] != '_') {
                    if (i > 0 && i < (arrPwdLen - 1)) {
                        nMidChar++;
                    }
                    if (nTmpSymbol != -1) {
                        if ((nTmpSymbol + 1) == i) {
                            nConsecSymbol++;
                            nConsecCharType++;
                        }
                    }
                    nTmpSymbol = i;
                    nSymbol++;
                }

                boolean bCharExists = false;
                for (int b = 0; b < arrPwdLen; b++) {
                    if (pwd2[i] == pwd2[b] && i != b) {
                        bCharExists = true;
                        nRepInc += Math.abs((double) arrPwdLen / (b - i));
                    }
                }
                if (bCharExists) {
                    nRepChar++;
                    nUnqChar = arrPwdLen - nRepChar;
                    nRepInc = (nUnqChar != 0) ? (int) Math.ceil(nRepInc / nUnqChar) : (int) Math.ceil(nRepInc);
                }
            }

            for (int s = 0; s < 22; s++) {
                String sFwd = sAlphas.substring(s, s + 3);
                String sRev = new StringBuffer(sFwd).reverse().toString();
                if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) {
                    nSeqAlpha++;
                    nSeqChar++;
                }
            }

            for (int s = 0; s < 8; s++) {
                String sFwd = sNumerics.substring(s, s + 3);
                String sRev = new StringBuffer(sFwd).reverse().toString();
                if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) {
                    nSeqNumber++;
                    nSeqChar++;
                }
            }

            for (int s = 0; s < 8; s++) {
                String sFwd = sSymbols.substring(s, s + 3);
                String sRev = new StringBuffer(sFwd).reverse().toString();
                if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) {
                    nSeqSymbol++;
                    nSeqChar++;
                }
            }

            System.out.println("nLengthBonus is: + " + score);

            if (nAlphaUC > 0 && nAlphaUC < nLength) {
                score = score + (nLength - nAlphaUC) * 2;
                sAlphaUC = "+ " + (nLength - nAlphaUC) * 2;
            }
            if (nAlphaLC > 0 && nAlphaLC < nLength) {
                score = score + (nLength - nAlphaLC) * 2;
                sAlphaLC = "+ " + (nLength - nAlphaLC) * 2;
            }
            if (nNumber > 0 && nNumber < nLength) {
                score = score + nNumber * nMultNumber;
                sNumber = "+ " + nNumber * nMultNumber;
            }
            if (nSymbol > 0) {
                score = score + nSymbol * nMultSymbol;
                sSymbol = "+ " + nSymbol * nMultSymbol;
            }
            if (nMidChar > 0) {
                score = score + nMidChar * nMultMidChar;
                sMidChar = "+ " + nMidChar * nMultMidChar;
            }

            System.out.println("nAlphaUCBonus is: " + sAlphaUC);
            System.out.println("nAlphaLCBonus is: " + sAlphaLC);
            System.out.println("nNumberBonus is: " + sNumber);
            System.out.println("nSymbolBonus is: " + sSymbol);
            System.out.println("nMidCharBonus is: " + sMidChar);

            if ((nAlphaLC > 0 || nAlphaUC > 0) && nSymbol == 0 && nNumber == 0) {
                score = score - nLength;
                nAlphasOnly = nLength;
                sAlphasOnly = "- " + nLength;
            }
            if (nAlphaLC == 0 && nAlphaUC == 0 && nSymbol == 0 && nNumber > 0) {
                score = score - nLength;
                nNumbersOnly = nLength;
                sNumbersOnly = "- " + nLength;
            }
            if (nRepChar > 0) {
                score = score - (int) nRepInc;
                sRepChar = "- " + nRepInc;
            }
            if (nConsecAlphaUC > 0) {
                score = score - nConsecAlphaUC * nMultConsecAlphaUC;
                sConsecAlphaUC = "- " + nConsecAlphaUC * nMultConsecAlphaUC;
            }
            if (nConsecAlphaLC > 0) {
                score = score - nConsecAlphaLC * nMultConsecAlphaLC;
                sConsecAlphaLC = "- " + nConsecAlphaLC * nMultConsecAlphaLC;
            }
            if (nConsecNumber > 0) {
                score = score - nConsecNumber * nMultConsecNumber;
                sConsecNumber = "- " + nConsecNumber * nMultConsecNumber;
            }
            if (nSeqAlpha > 0) {
                score = score - nSeqAlpha * nMultSeqAlpha;
                sSeqAlpha = "- " + nSeqAlpha * nMultSeqAlpha;
            }
            if (nSeqNumber > 0) {
                score = score - nSeqNumber * nMultSeqNumber;
                sSeqNumber = "- " + nSeqNumber * nMultSeqNumber;
            }
            if (nSeqSymbol > 0) {
                score = score - nSeqSymbol * nMultSeqSymbol;
                sSeqSymbol = "- " + nSeqSymbol * nMultSeqSymbol;
            }

            System.out.println("nAlphasOnlyBonus is: " + sAlphasOnly);
            System.out.println("nNumbersOnlyBonus is: " + sNumbersOnly);
            System.out.println("sRepCharBonus is: " + sRepChar);
            System.out.println("nConsecAlphaUCBonus is: " + sConsecAlphaUC);
            System.out.println("nConsecAlphaLCBonus is: " + sConsecAlphaLC);
            System.out.println("nConsecNumberBonus is: " + sConsecNumber);
            System.out.println("nSeqAlphaBonus is: " + sSeqAlpha);
            System.out.println("nSeqNumberBonus is: " + sSeqNumber);
            System.out.println("nSeqSymbolBonus is: " + sSeqSymbol);

            int[] arrChars = {nLength, nAlphaUC, nAlphaLC, nNumber, nSymbol};
            String[] arrCharsIds = {"nLength", "nAlphaUC", "nAlphaLC", "nNumber", "nSymbol"};
            int arrCharsLen = arrChars.length;
            for (int c = 0; c < arrCharsLen; c++) {
                int minVal;
                if (arrCharsIds[c].equals("nLength")) {
                    minVal = MIN_PASSWORD_LENGTH - 1;
                } else {
                    minVal = 0;
                }
                if (arrChars[c] == (minVal + 1)) {
                    nReqChar++;
                } else if (arrChars[c] > (minVal + 1)) {
                    nReqChar++;
                }
            }

            nRequirements = nReqChar;
            int nMinReqChars;
            if (pwd.length() >= MIN_PASSWORD_LENGTH) {
                nMinReqChars = 3;
            } else {
                nMinReqChars = 4;
            }
            if (nRequirements > nMinReqChars) {
                score = score + nRequirements * 2;
                sRequirements = "+ " + nRequirements * 2;
            }

            System.out.println("nRequirementsBonus is: " + sRequirements);

            if (score > 100) {
                score = 100;
            } else if (score < 0) {
                score = 0;
            }
            if (score >= 0 && score < 20) {
                result = VERY_WEAK;
            } else if (score >= 20 && score < 40) {
                result = WEAK;
            } else if (score >= 40 && score < 60) {
                result = MEDIUM;
            } else if (score >= 60 && score < 80) {
                result = STRONG;
            } else if (score >= 80 && score <= 100) {
                result = VERY_STRONG;
            }

            System.out.println("Strength score is: " + score + "%");
            System.out.println("Strength verdict: " + result);
        } else {
            System.out.println("Strength score is:" + score + "%");
            System.out.println("Strength verdict: " + result);
        }
    }

    private boolean isPasswordValid(String pwd) {
        return pwd != null && !pwd.isEmpty();
    }
}